/**
 * @Creator: eyes
 * @Date: 2020/3/31
 * 用户特征模块, 「更多筛选条件」, 单个可选项的实现
 */

import React, {useState, useEffect, useCallback} from 'react';
import {Form} from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import {Select} from 'antd';
import {throttle} from 'lodash';
import {getFieldValues} from '~/service/performance';

const popUpContainer = triggerNode => triggerNode.parentElement;

const FormItem = Form.Item;
const SelectOption = Select.Option;

const INIT_PAGER = {
    pageSize: 100,
    pageNum: 1,
};
const SCROLL_OFFSET = 50;
const SEARCH_WAIT_TIME = 200;

/**
 * @param label FormItem label
 * @param field 当前option组件负责处理的域, eg: province 省份
 * @param getFieldDecorator -
 * @param onChange -
 * @returns {*}
 */
export default ({label, field, getFieldDecorator, onChange}) => {

    const [keyword, setKeyword] = useState('');
    const [loading, setLoading] = useState(false);
    const [list, setList] = useState([]);
    const [pager, setPager] = useState(INIT_PAGER);
    const [hasNext, setHasNext] = useState(null);

    // 初次加载/滚动分页/搜索/搜索后分页的通用数据加载方法
    // searchMode: 是否为手动搜索的模式, true的话则替换当前list
    // keywordOnSearch: 用于搜索时直接传入keyword
    const loadData = useCallback(async (searchMode = false, keywordOnSearch) => {
        setLoading(true);
        const res = await getFieldValues({
            field,
            keyword: searchMode ? keywordOnSearch : keyword,
            pager: searchMode ? INIT_PAGER : pager,
        });
        const values = res?.data?.values;
        const pageSize = res?.pager?.pageSize;
        const pageNum = res?.pager?.pageNum;
        const count = res?.pager?.count;
        if (values) {
            setList(searchMode ? values : [...list, ...values]);
        }
        setPager({
            pageSize,
            pageNum: pageNum + 1,
        });
        setHasNext(pageSize * pageNum < count);
        setLoading(false);
    }, [field, keyword, pager]);

    // 组件挂载时加载第一页数据
    useEffect(() => {
        loadData();
    }, []);

    // 滚动到底部时分页加载(常规态和搜索态, 或者说都携带keyword, 这样不用区分)
    const onScroll = useCallback(e => {
        e.persist();
        const {target: {scrollTop, offsetHeight, scrollHeight}} = e;
        if (!loading && hasNext && (scrollHeight - (scrollTop + offsetHeight) < SCROLL_OFFSET)) {
            loadData();
        }
    }, [hasNext, loading, loadData]);

    // 触发搜索时, 加载新list全量替换旧list
    const onSearch = useCallback(throttle(keyword => {
        setKeyword(keyword);
        setPager(INIT_PAGER);
        loadData(true, keyword);
    }, SEARCH_WAIT_TIME, {leading: false}), [loadData]);

    // 失去焦点时取消搜索相关状态.
    const onBlur = useCallback(() => {
        keyword && onSearch('');
    }, [keyword, onSearch]);

    return (
        <FormItem
            label={label}
            labelAlign="right"
            key={field}
        >
            {
                getFieldDecorator(field)(
                    <Select
                        className="user-feature-select-multiple"
                        placeholder="请选择"
                        notFoundContent="暂无数据"
                        loading={loading}
                        mode="multiple"
                        showSearch
                        optionFilterProp="children"
                        getPopupContainer={popUpContainer}
                        onPopupScroll={onScroll}
                        onChange={onChange}
                        onSearch={onSearch}
                        onBlur={onBlur}
                    >
                        {
                            list.map(item => (
                                <SelectOption value={item} key={item}>
                                    {item}
                                </SelectOption>
                            ))
                        }
                    </Select>,
                )
            }
        </FormItem>
    );
};
